package com.iwithlong.filter.handler;

import com.iwithlong.filter.exceptions.ForwardException;
import com.iwithlong.filter.http.HttpHandler;
import com.iwithlong.filter.http.HttpHandlerFactory;
import com.iwithlong.filter.http.RequestInfo;
import com.iwithlong.filter.http.ResponseInfo;
import com.iwithlong.filter.utils.PropertyUtils;
import com.ktanx.platform.web.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import static com.iwithlong.filter.utils.ForwardHttpUtils.*;


/**
 * Created by liyingdan on 2017/1/5.
 */
@Slf4j
public class DefaultForwardHandler implements ForwardHandler {

    private String forwardName;

    public DefaultForwardHandler(String forwardName) {
        this.forwardName = forwardName;
    }

    public boolean isValid(String requestURI, HttpServletRequest request) {
        return true;
    }

    public RequestInfo buildForwardRequestInfo(HttpServletRequest request) {

        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setScheme(request.getScheme());
        requestInfo.setMethod(request.getMethod());
        requestInfo.setRequestURI(request.getRequestURI());
        requestInfo.setRequestUrl(request.getRequestURL().toString());

        String servletPath = request.getServletPath();
        String pathInfo = request.getPathInfo();
        if (StringUtils.length(pathInfo) > 0) {
            servletPath = servletPath + pathInfo;
        }
        requestInfo.setServletPath(servletPath);
        requestInfo.setQueryString(request.getQueryString());
        requestInfo.setEncodeQueryString(getEncodeQueryString(request));
        requestInfo.setRemoteIP(getRemoteIP(request));
        requestInfo.setParams(getParams(request));
        requestInfo.setHeaders(getHeaders(request));
        requestInfo.setCookies(getCookies(request));

        return requestInfo;
    }

    public ResponseInfo requestTargetServer(RequestInfo requestInfo, String forwardUrl, HttpServletRequest request) {
//        forwardUrl = PropertyUtils.getProperty("agent.properties",forwardUrl);
//        if (StringUtils.isNotBlank(requestInfo.getQueryString())) {
//            forwardUrl = forwardUrl + "?" + requestInfo.getEncodeQueryString();
//        }
        ResponseInfo responseInfo = null;
        HttpHandler httpHandler = HttpHandlerFactory.getHttpHandler(HttpHandlerFactory.DEFAULT_HANDLER);
        if ("post".equalsIgnoreCase(requestInfo.getMethod())) {

            // 创建一个通用的多部分解析器
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession()
                    .getServletContext());

            // 判断 request 是否有文件上传,即多部分请求
            if (multipartResolver.isMultipart(request)) {
                log.info("文件上传转发请求");
                MultipartHttpServletRequest multipartRequest = multipartResolver.resolveMultipart(request);
                Map<String, MultipartFile> filesMap = multipartRequest.getFileMap();
                Collection<MultipartFile> multipartFiles = filesMap.values();
                for (MultipartFile mf : multipartFiles) {
                    //获取原始文件名
                    String originalFilename = mf.getOriginalFilename();
                    //获取文件流，可以进行处理
                    try {
                        responseInfo = httpHandler.postMultipart(forwardUrl, requestInfo, originalFilename, mf.getInputStream());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            } else {
                responseInfo = httpHandler.post(forwardUrl, requestInfo);
            }
        } else if ("get".equalsIgnoreCase(requestInfo.getMethod())) {
            responseInfo = httpHandler.get(forwardUrl, requestInfo);
        } else {
            throw new ForwardException("", "不支持的代理方式:" + requestInfo.getMethod());
        }
        return responseInfo;
    }

    public boolean writeResponse(ResponseInfo responseInfo, HttpServletRequest request, HttpServletResponse response) {

        if (responseInfo.getBody() != null) {
            try {
                response.setContentType(responseInfo.getContentType());
                response.getOutputStream().write(responseInfo.getBody());
            } catch (Exception e) {
                throw new ForwardException("", "写入返回数据失败:", e);
            }
        }
        return false;
    }

    @Override
    public boolean isFilter ( RequestInfo requestInfo, HttpServletRequest request ) {
        return true;
    }

}
